<?php
declare (strict_types=1);

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;
use GuzzleHttp\Client;
use Obs\ObsClient;

// 导入数据
class UrlToObs extends Command
{
    // 配置信息
    private $config = [];

    // OBS客户端
    private $obsClient;

    protected function configure()
    {
        $this->setName('oss-to-obs')->setDescription('将阿里云OSS图片迁移至华为云OBS');
    }

    protected function execute(Input $input, Output $output)
    {
        ini_set('memory_limit', '1024M');

        // 加载配置
        $this->config = [
            // 每批处理数量
            'batch_size' => 20,
            // 并发请求数
            'concurrency' => 5,
            // 每批处理后休眠时间(秒)
            'sleep_time' => 1,

            'table_name' => 'lp_xcxx',

            'obs_bucket' => 'mzsz-muziyun-net1',
            'obs_key' => 'Q2DFOGJZBRHD0TPSTLN6',
            'obs_secret' => 'nmcMya1YXICjuZsC7DXT8jTsa4rA5v0V6JEzSmkb',
            'obs_endpoint' => 'https://obs.cn-east-3.myhuaweicloud.com',
            'obs_dir' => 'szxc',
        ];

        $table_name = 'js_lp_xm_img';

        // 初始化OBS客户端
        $this->obsClient = new ObsClient([
            'key' => $this->config['obs_key'],
            'secret' => $this->config['obs_secret'],
            'endpoint' => $this->config['obs_endpoint'],
        ]);

        $where = [
            ['image_url', 'like', '%%3FimageMogr%'],
        ];
        // 获取总记录数
        $totalRecords = Db::table($table_name)->where($where)->count();
        $output->writeln("共有 {$totalRecords} 条记录");

        $totalPages = ceil($totalRecords / $this->config['batch_size']);

        $output->writeln("开始迁移图片，总共 {$totalRecords} 条记录需要处理");

        // 分页处理记录
        for ($page = 1; $page <= $totalPages; $page++) {
            $output->writeln("正在处理第 " . ($page) . "/" . $totalPages . " 页，共 {$this->config['batch_size']} 条记录");

            $records = Db::table($table_name)
                ->where($where)
                ->page($page, $this->config['batch_size'])
                ->select();

            // 上传图片
            $client = new Client();
            $successIds = [];

            foreach ($records as $record) {
                $img_url = urldecode($record['image_url']);
                if (!$img_url || $record['tag'] == 1) continue;

                if (str_contains($img_url, 'index.html') || str_contains($img_url, '720yun')) continue;

                if (str_contains($img_url, 'hotspot/preview')) continue;

                // 提取路径部分
                $object_name = parse_url($img_url, PHP_URL_PATH);
                if (!empty($this->config['obs_dir'])) {
                    $object_name = $this->config['obs_dir'] . $object_name;
                }
                try {
                    $response = $client->get($img_url, ['stream' => true]); // 流式下载
                    $body = $response->getBody();

                    $this->obsClient->putObject([
                        'Bucket' => $this->config['obs_bucket'],
                        'Key' => ltrim($object_name, '/'),
                        'Body' => $body->getContents() // 获取内容流
                    ]);
                    $successIds[] = $record['id'];
                    $output->writeln("{$object_name}上传成功");
                } catch (\Exception $e) {
                    $output->writeln($e->getMessage());
                }
            }
            unset($records);
            if (!empty($successIds)) {
                Db::table($table_name)->whereIn('id', $successIds)->update(['tag' => 1]);
            }

            // 休眠，避免请求过于频繁
            $output->writeln("休眠 {$this->config['sleep_time']} 秒后继续...");
            sleep($this->config['sleep_time']);
        }

        $output->writeln("图片迁移完成！");
    }
}
